home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
libgutil
/
invgamma.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
4KB
|
189 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* invgamma -
* Invert arbitrary gamma look up tables.
*
* Paul Haeberli - 1991
*/
#include "stdio.h"
#include "math.h"
static makeinvtab();
#define TESTING
#ifdef TESTING
short mytab[256];
main()
{
int i;
fprintf(stderr,"mytab\n");
for(i=0; i<256; i++) {
mytab[i] = rand()%256; /* for random ramp */
mytab[i] = 255.0*pow(i/255.0,0.5)+0.499; /* for gamma 2.0 ramp*/
fprintf(stderr,"%3d ",mytab[i]);
}
fprintf(stderr,"\n");
newgammaramp(mytab,mytab,mytab);
}
#endif
#define TABSIZE (256)
static short rtab[TABSIZE];
static short gtab[TABSIZE];
static short btab[TABSIZE];
static short irtab[TABSIZE];
static short igtab[TABSIZE];
static short ibtab[TABSIZE];
newgammaramp(r,g,b)
short r[TABSIZE], g[TABSIZE], b[TABSIZE];
{
bcopy(r,rtab,TABSIZE*sizeof(short));
bcopy(g,gtab,TABSIZE*sizeof(short));
bcopy(b,btab,TABSIZE*sizeof(short));
makeinvtab(rtab,irtab);
makeinvtab(gtab,igtab);
makeinvtab(btab,ibtab);
}
static short *randorder;
static short order[TABSIZE];
static short *sortdata;
static int cmpfunc(v1,v2)
short *v1, *v2;
{
int i1, i2;
i1 = sortdata[*v1];
i2 = sortdata[*v2];
if(i1<i2)
return -1;
if(i1>i2)
return 1;
if(*v1<*v2)
return -1;
if(*v1>*v2)
return 1;
return 0;
}
static int delta(a,b)
{
int d;
d = a-b;
if(d>0)
return d;
else
return -d;
}
static makeinvtab(tab,itab)
short tab[TABSIZE], itab[TABSIZE];
{
int i, pos, temp;
int start, inpos, below, above;
/* make randomized order table if we must */
if(!randorder) {
randorder = (short *)mymalloc(TABSIZE*sizeof(short));
for(i=0; i<TABSIZE; i++)
randorder[i] = i;
for(i=0; i<TABSIZE; i++) {
pos = i+rand()%(TABSIZE-i);
temp = randorder[pos];
randorder[pos] = randorder[i];
randorder[i] = temp;
}
}
/* start with randomized order so qsort will run fast */
bcopy(randorder,order,TABSIZE*sizeof(short));
/* sort the table into increasing order */
sortdata = tab;
qsort(order,TABSIZE,sizeof(short),cmpfunc);
/* make the inverse table */
start = 0;
for(i=0; i<TABSIZE; i++) {
inpos = start;
while(inpos<256) {
if(tab[order[inpos]]<=i) {
above = below = order[inpos];
start = inpos;
}
if(tab[order[inpos]]>=i) {
above = order[inpos];
break;
}
inpos++;
}
if(delta(i,tab[below])<delta(i,tab[above]))
itab[i] = below;
else
itab[i] = above;
}
#ifdef TESTING
/* print the inverse table */
fprintf(stderr,"inverse\n");
for(i=0; i<TABSIZE; i++)
fprintf(stderr,"%3d ",itab[i]);
fprintf(stderr,"\n");
/* print the result table */
fprintf(stderr,"result\n");
for(i=0; i<TABSIZE; i++)
fprintf(stderr,"%3d ",tab[itab[i]]);
fprintf(stderr,"\n");
#endif
}
/*
* toguns -
* takes an rgb triple 0..255 and translates it to gun
* rgb triple 0..255
*
*/
toguns(r,g,b,rgun,ggun,bgun)
int r, g, b, *rgun, *ggun, *bgun;
{
*rgun = rtab[r];
*ggun = gtab[g];
*bgun = btab[b];
}
/*
* fromguns -
* takes a gun rgb triple 0..255 and translates it to an
* rgb triple 0..255
*
*/
fromguns(rgun,ggun,bgun,r,g,b)
int rgun, ggun, bgun, *r, *g, *b;
{
*r = irtab[rgun];
*g = igtab[ggun];
*b = ibtab[bgun];
}